#include "app_pool.h"

static mqd_t mqd;

static pthread_t threads[MAX_THREAD_NUM];

/**
 * @brief 线程处理函数  
 * 1 不停的尝试从队列中获取任务
 * 2 一旦获取到任务 就执行该任务 
 */
static void *app_pool_thread_handler(void *arg)
{ 
    while(1)
    {
      //  1 不停的尝试从队列中获取任务
        app_pool_task_t  pool_task;
        int size= mq_receive(mqd, (char *)&pool_task, sizeof(app_pool_task_t), 0);
        if(size>0)
        {
            // 2 一旦获取到任务 就执行该任务 
            pool_task.task_func(pool_task.arg);
        }

    }
    return NULL;
}

/**
 * @brief 初始化线程池
 * 1 创建任务队列
 * 2 创建线程数组
 * 
 */
int app_pool_init(void)
{

    struct mq_attr attr;
    attr.mq_msgsize=sizeof(app_pool_task_t);
    attr.mq_maxmsg=10;
//  * 1 创建任务队列
    mqd= mq_open(POOL_MQ_NAME,O_CREAT|O_RDWR,0666,&attr);
    if(mqd==-1)
    {
        perror("mq_open");
        return -1;
    }

//  * 2 创建线程数组
    for (size_t i = 0; i < MAX_THREAD_NUM; i++)
    {
        pthread_create(&threads[i],NULL,app_pool_thread_handler,NULL);
    }
    log_info("app_pool_init success");

    return 0;
    
}




/**
 * @brief 向线程池提交任务
 */
int app_pool_submitTask(void *(*func)(void *arg), void *arg)
{
    //  1 装配任务
    app_pool_task_t pool_task={
        .arg=arg,
        .task_func=func
    };
    //  2 添加任务 
    //     本质上是把数据拷贝一份到队列中
    mq_send(mqd,(char *)&pool_task,sizeof(app_pool_task_t),0);

    return 0;

}

/**
 * @brief 销毁线程池 
 * 1 逐个停掉线程   
 * 2 销毁队列
 */
void app_pool_destroy(void)
{
    // * 1 逐个停掉线程   
    for (size_t i = 0; i < MAX_THREAD_NUM; i++)
    {
        pthread_cancel(threads[i]);
    }
    // 2 等待线程销毁
     for (size_t i = 0; i < MAX_THREAD_NUM; i++)
    {
        pthread_join(threads[i],NULL);
    }
    log_info("线程已经结束");


    // * 2 销毁队列
    mq_close(mqd);
    mq_unlink(POOL_MQ_NAME);
}